import { api } from '../../utils/api';

const recorderManager = wx.getRecorderManager();
const innerAudioContext = wx.createInnerAudioContext();

Page({
  data: {
    otherUserId: 0,
    messages: [] as any[],
    inputText: '',
    isRecording: false,
    recordDuration: 0,
    recordTimer: null as any,
    currentUser: null as any,
    otherUser: null as any,
    websocket: null as WechatMiniprogram.SocketTask | null,
    voiceMode: false, // 语音模式
    showMoreMenu: false, // 显示更多选项菜单
    recordCanceled: false, // 录音是否被取消
    recordStartY: 0, // 录音开始时的Y坐标
  },

  onLoad(options: any) {
    const otherUserId = parseInt(options.userId);
    if (!otherUserId) {
      wx.showToast({
        title: '参数错误',
        icon: 'none',
      });
      wx.navigateBack();
      return;
    }

    this.setData({
      otherUserId,
    });

    this.loadUserInfo();
    this.loadOtherUserInfo();
    this.loadMessages();
    this.connectWebSocket();
    this.setupRecorder();
  },

  onShow() {
    this.markConversationAsRead();
  },

  onUnload() {
    if (this.data.websocket) {
      this.data.websocket.close({});
    }
    recorderManager.stop();
    innerAudioContext.destroy();
    if (this.data.recordTimer) {
      clearInterval(this.data.recordTimer);
    }
  },

  async loadUserInfo() {
    try {
      // 优先从缓存读取用户信息
      const cachedUser = wx.getStorageSync('currentUser');
      if (cachedUser) {
        this.setData({
          currentUser: {
            ...cachedUser,
            avatar: cachedUser.avatar || null,
          },
        });
      }
      
      // 同时从后端获取最新用户信息并更新缓存
      const res: any = await api.getCurrentUser();
      if (res.success && res.user) {
        // 更新缓存
        wx.setStorageSync('currentUser', res.user);
        // 更新页面数据
        this.setData({
          currentUser: {
            ...res.user,
            avatar: res.user.avatar || null,
          },
        });
      }
      console.log("currentUser:", this.data.currentUser)
    } catch (error) {
      console.error('加载用户信息失败:', error);
      // 如果接口失败，至少使用缓存的数据
      const cachedUser = wx.getStorageSync('currentUser');
      if (cachedUser) {
        this.setData({
          currentUser: {
            ...cachedUser,
            avatar: cachedUser.avatar || null,
          },
        });
      }
    }
  },

  async loadOtherUserInfo() {
    try {
      // 从联系人列表中获取对方用户信息
      const res: any = await api.getContacts();
      if (res.success && res.contacts) {
        const contact = res.contacts.find((c: any) => c.contactId === this.data.otherUserId);
        if (contact) {
          this.setData({
            otherUser: {
              id: contact.contactId,
              nickname: contact.nickname || `用户${contact.contactId}`,
              avatar: contact.avatar || null,
              username: contact.username || '',
            },
          });
        }
      }
    } catch (error) {
      console.error('加载对方用户信息失败:', error);
    }
  },

  async loadMessages() {
    try {
      const res: any = await api.getConversation(this.data.otherUserId);
      if (res.success && res.messages) {
        // 处理消息，添加时间显示标记
        const processedMessages = this.processMessagesWithTime(res.messages);
        this.setData({
          messages: processedMessages,
        });
        // 滚动到底部
        this.scrollToBottom();
      }
    } catch (error) {
      console.error('加载消息失败:', error);
    }
  },

  processMessagesWithTime(messages: any[]) {
    if (!messages || messages.length === 0) return [];
    
    // 过滤掉已有的时间标记，只处理真实消息
    const realMessages = messages.filter((msg: any) => msg.type !== 'time');
    if (realMessages.length === 0) return messages;
    
    let lastTime = 0;
    const processed: any[] = [];
    
    realMessages.forEach((msg, index) => {
      // 解析时间，支持 "yyyy-MM-dd HH:mm:ss" 格式
      let msgTime: number;
      if (typeof msg.createdAt === 'string') {
        if (msg.createdAt.includes(' ')) {
          // "yyyy-MM-dd HH:mm:ss" 格式
          const dateStr = msg.createdAt.replace(' ', 'T');
          const tempDate = new Date(dateStr);
          
          // 如果解析失败，尝试手动解析（作为备用方案）
          if (isNaN(tempDate.getTime())) {
            const parts = msg.createdAt.split(' ');
            const dateParts = parts[0].split('-');
            const timeParts = parts[1].split(':');
            const manualDate = new Date(
              parseInt(dateParts[0]),      // 年
              parseInt(dateParts[1]) - 1,   // 月（0-11）
              parseInt(dateParts[2]),       // 日
              parseInt(timeParts[0]),      // 时
              parseInt(timeParts[1]),       // 分
              parseInt(timeParts[2] || '0') // 秒
            );
            msgTime = manualDate.getTime();
          } else {
            msgTime = tempDate.getTime();
          }
        } else {
          msgTime = new Date(msg.createdAt).getTime();
        }
      } else {
        msgTime = new Date(msg.createdAt).getTime();
      }
      
      // 如果时间无效，跳过
      if (isNaN(msgTime)) {
        console.warn('无效的消息时间:', msg.createdAt);
        processed.push(msg);
        return;
      }
      
      // 如果两条消息间隔超过5分钟，显示时间分隔
      const showTime = index === 0 || (msgTime - lastTime > 5 * 60 * 1000);
      
      if (showTime) {
        // 预先格式化时间文本
        const formattedTime = this.formatTime(msg.createdAt, true);
        processed.push({
          type: 'time',
          createdAt: msg.createdAt,
          formattedTime: formattedTime, // 存储格式化后的时间文本
          showTime: true,
        });
      }
      
      processed.push(msg);
      lastTime = msgTime;
    });
    
    return processed;
  },

  async markConversationAsRead() {
    try {
      await api.markConversationAsRead(this.data.otherUserId);
    } catch (error) {
      console.error('标记已读失败:', error);
    }
  },

  scrollToBottom() {
    setTimeout(() => {
      wx.pageScrollTo({
        scrollTop: 99999,
        duration: 300,
      });
    }, 100);
  },

  connectWebSocket() {
    const token = api.getToken();
    const userId = this.data.currentUser?.id;
    if (!token || !userId) {
      setTimeout(() => this.connectWebSocket(), 1000);
      return;
    }

    const ws = wx.connectSocket({
      url: `ws://localhost:8080/ws/message?userId=${userId}`,
      header: {
        token,
      },
    });

    ws.onMessage((res: any) => {
      try {
        const message = JSON.parse(res.data);
        if (message.receiverId === this.data.currentUser?.id || 
            message.senderId === this.data.otherUserId) {
          const processedMessages = this.processMessagesWithTime([...this.data.messages, message]);
          this.setData({
            messages: processedMessages,
          });
          this.scrollToBottom();
          this.markConversationAsRead();
        }
      } catch (e) {
        console.error('解析WebSocket消息失败:', e);
      }
    });

    this.setData({
      websocket: ws,
    });
  },

  // 切换语音模式
  toggleVoiceMode() {
    this.setData({
      voiceMode: !this.data.voiceMode,
      showMoreMenu: false, // 关闭更多菜单
    });
  },

  // 切换更多菜单
  toggleMoreMenu() {
    this.setData({
      showMoreMenu: !this.data.showMoreMenu,
    });
  },

  // 关闭更多菜单
  closeMoreMenu() {
    this.setData({
      showMoreMenu: false,
    });
  },

  // 选择图片
  onChooseImage(e: any) {
    e.stopPropagation && e.stopPropagation();
    this.closeMoreMenu();
    this.chooseImage();
  },

  // 发送位置
  onSendLocation(e: any) {
    e.stopPropagation && e.stopPropagation();
    this.closeMoreMenu();
    this.sendLocation();
  },
  
  // 阻止菜单内容区域的点击事件冒泡
  onMenuContentTap(e: any) {
    e.stopPropagation && e.stopPropagation();
  },

  onInputChange(e: any) {
    this.setData({
      inputText: e.detail.value,
    });
  },

  async sendTextMessage() {
    const content = this.data.inputText.trim();
    if (!content) return;

    const message = {
      receiverId: this.data.otherUserId,
      messageType: 'TEXT',
      content,
    };

    try {
      const res: any = await api.sendMessage(message);
      if (res.success && res.message) {
        const processedMessages = this.processMessagesWithTime([...this.data.messages, res.message]);
        this.setData({
          messages: processedMessages,
          inputText: '',
        });
        this.scrollToBottom();
      }
    } catch (error) {
      wx.showToast({
        title: '发送失败',
        icon: 'none',
      });
    }
  },

  // 语音录制
  setupRecorder() {
    recorderManager.onStart(() => {
      this.setData({
        isRecording: true,
        recordDuration: 0,
      });

      const timer = setInterval(() => {
        const duration = this.data.recordDuration + 1;
        this.setData({
          recordDuration: duration,
        });

        // 60秒自动停止
        if (duration >= 60) {
          this.stopRecord();
        }
      }, 1000);

      this.setData({
        recordTimer: timer,
      });
    });

    recorderManager.onStop((res) => {
      if (this.data.recordTimer) {
        clearInterval(this.data.recordTimer);
        this.setData({
          recordTimer: null,
        });
      }

      // 如果被取消了，不上传
      if (this.data.recordCanceled) {
        this.setData({
          isRecording: false,
          recordDuration: 0,
          recordCanceled: false,
        });
        return;
      }

      if (res.duration > 1000) { // 至少1秒
        this.uploadVoice(res.tempFilePath, res.duration);
      }

      this.setData({
        isRecording: false,
        recordDuration: 0,
        recordCanceled: false,
      });
    });

    recorderManager.onError((err) => {
      console.error('录音错误:', err);
      this.setData({
        isRecording: false,
        recordDuration: 0,
      });
    });
  },

  // 语音输入按钮触摸开始
  onVoiceTouchStart(e: any) {
    const touch = e.touches[0];
    this.setData({
      recordStartY: touch.clientY,
      recordCanceled: false,
    });
    
    // 开始录音
    recorderManager.start({
      duration: 60000,
      sampleRate: 16000,
      numberOfChannels: 1,
      encodeBitRate: 96000,
      format: 'mp3',
    });
  },

  // 语音输入按钮触摸移动（上滑取消）
  onVoiceTouchMove(e: any) {
    if (!this.data.isRecording) return;
    
    const touch = e.touches[0];
    const currentY = touch.clientY;
    const startY = this.data.recordStartY;
    const moveY = startY - currentY; // 向上滑动为正值
    
    // 如果上滑超过50rpx，则取消录音
    if (moveY > 50) {
      this.setData({
        recordCanceled: true,
      });
    } else {
      this.setData({
        recordCanceled: false,
      });
    }
  },

  // 语音输入按钮触摸结束
  onVoiceTouchEnd(_e: any) {
    if (this.data.recordCanceled) {
      // 取消录音
      recorderManager.stop();
      this.setData({
        isRecording: false,
        recordDuration: 0,
        recordCanceled: false,
      });
    } else {
      // 正常结束录音
      recorderManager.stop();
    }
  },

  // 语音输入按钮触摸取消
  onVoiceTouchCancel(_e: any) {
    recorderManager.stop();
    this.setData({
      isRecording: false,
      recordDuration: 0,
      recordCanceled: false,
    });
  },

  startRecord() {
    recorderManager.start({
      duration: 60000,
      sampleRate: 16000,
      numberOfChannels: 1,
      encodeBitRate: 96000,
      format: 'mp3',
    });
  },

  stopRecord() {
    recorderManager.stop();
  },

  cancelRecord() {
    recorderManager.stop();
    this.setData({
      isRecording: false,
      recordDuration: 0,
    });
  },

  async uploadVoice(filePath: string, duration: number) {
    wx.showLoading({
      title: '上传中...',
    });

    try {
      const res: any = await api.uploadFile(filePath, 'VOICE');
      if (res.success && res.file) {
        const message = {
          receiverId: this.data.otherUserId,
          messageType: 'VOICE',
          filePath: res.file.filePath,
          voiceDuration: Math.floor(duration / 1000),
        };

        const sendRes: any = await api.sendMessage(message);
        if (sendRes.success && sendRes.message) {
          const processedMessages = this.processMessagesWithTime([...this.data.messages, sendRes.message]);
          this.setData({
            messages: processedMessages,
          });
          this.scrollToBottom();
        }
      }
    } catch (error) {
      wx.showToast({
        title: '上传失败',
        icon: 'none',
      });
    } finally {
      wx.hideLoading();
    }
  },

  async chooseImage() {
    wx.chooseImage({
      count: 1,
      sizeType: ['compressed'],
      sourceType: ['album', 'camera'],
      success: async (res) => {
        const tempFilePath = res.tempFilePaths[0];
        wx.showLoading({
          title: '上传中...',
        });

        try {
          const uploadRes: any = await api.uploadFile(tempFilePath, 'IMAGE');
          if (uploadRes.success && uploadRes.file) {
            const message = {
              receiverId: this.data.otherUserId,
              messageType: 'IMAGE',
              filePath: uploadRes.file.filePath,
            };

            const sendRes: any = await api.sendMessage(message);
            if (sendRes.success && sendRes.message) {
              const messages = [...this.data.messages, sendRes.message];
              this.setData({
                messages,
              });
              this.scrollToBottom();
            }
          }
        } catch (error) {
          wx.showToast({
            title: '上传失败',
            icon: 'none',
          });
        } finally {
          wx.hideLoading();
        }
      },
    });
  },

  async sendLocation() {
    wx.getLocation({
      type: 'gcj02',
      success: async (res) => {
        wx.showLoading({
          title: '获取地址中...',
        });

        // 获取地址信息（这里简化处理，实际应调用地图API）
        const address = `纬度: ${res.latitude}, 经度: ${res.longitude}`;

        const message = {
          receiverId: this.data.otherUserId,
          messageType: 'LOCATION',
          latitude: res.latitude,
          longitude: res.longitude,
          address,
        };

        try {
          const sendRes: any = await api.sendMessage(message);
          if (sendRes.success && sendRes.message) {
            const processedMessages = this.processMessagesWithTime([...this.data.messages, sendRes.message]);
            this.setData({
              messages: processedMessages,
            });
            this.scrollToBottom();
          }
        } catch (error) {
          wx.showToast({
            title: '发送失败',
            icon: 'none',
          });
        } finally {
          wx.hideLoading();
        }
      },
      fail: () => {
        wx.showToast({
          title: '获取位置失败',
          icon: 'none',
        });
      },
    });
  },

  previewImage(e: any) {
    const url = e.currentTarget.dataset.url;
    wx.previewImage({
      urls: [url],
      current: url,
    });
  },

  openLocation(e: any) {
    const { latitude, longitude, address } = e.currentTarget.dataset;
    wx.openLocation({
      latitude: parseFloat(latitude),
      longitude: parseFloat(longitude),
      name: address || '位置',
      scale: 18,
    });
  },

  playVoice(e: any) {
    const url = e.currentTarget.dataset.url;
    innerAudioContext.src = url;
    innerAudioContext.play();
  },

  async deleteMessage(e: any) {
    const messageId = e.currentTarget.dataset.id;
    wx.showModal({
      title: '提示',
      content: '确定要删除这条消息吗？',
      success: async (res) => {
        if (res.confirm) {
          try {
            await api.deleteMessage(messageId);
            const messages = this.data.messages.filter((msg: any) => msg.id !== messageId);
            this.setData({
              messages,
            });
          } catch (error) {
            wx.showToast({
              title: '删除失败',
              icon: 'none',
            });
          }
        }
      },
    });
  },

  onAvatarError(e: any) {
    // 头像加载失败时，切换到占位符显示
    console.log('头像加载失败:', e);
    // 如果头像加载失败，让 WXML 重新渲染，显示占位符
    // 这里可以通过设置 avatar 为 null 来触发重新渲染
    const currentUser = this.data.currentUser;
    
    const otherUser = this.data.otherUser;
    
    if (currentUser && currentUser.avatar) {
      currentUser.avatar = null;
      this.setData({ currentUser });
    }
    if (otherUser && otherUser.avatar) {
      otherUser.avatar = null;
      this.setData({ otherUser });
    }
  },

  formatTime(timestamp: any, fullFormat: boolean = false) {
    if (!timestamp) {
      return '';
    }
    
    // 处理字符串格式 "yyyy-MM-dd HH:mm:ss" 或 ISO 格式
    let date: Date;
    try {
      if (typeof timestamp === 'string') {
        // 如果包含空格，说明是 "yyyy-MM-dd HH:mm:ss" 格式
        if (timestamp.includes(' ')) {
          // 将 "yyyy-MM-dd HH:mm:ss" 转换为 ISO 格式 "yyyy-MM-ddTHH:mm:ss"
          // JavaScript 会自动将其解析为本地时间
          const dateStr = timestamp.replace(' ', 'T');
          date = new Date(dateStr);
          
          // 如果解析失败，尝试手动解析（作为备用方案）
          if (isNaN(date.getTime())) {
            const parts = timestamp.split(' ');
            if (parts.length < 2) {
              return '';
            }
            const dateParts = parts[0].split('-');
            const timeParts = parts[1].split(':');
            
            if (dateParts.length < 3 || timeParts.length < 2) {
              return '';
            }
            
            date = new Date(
              parseInt(dateParts[0]),      // 年
              parseInt(dateParts[1]) - 1,   // 月（0-11）
              parseInt(dateParts[2]),       // 日
              parseInt(timeParts[0]),       // 时
              parseInt(timeParts[1]),       // 分
              parseInt(timeParts[2] || '0') // 秒
            );
          }
        } else {
          date = new Date(timestamp);
        }
      } else {
        date = new Date(timestamp);
      }
      
      // 检查日期是否有效
      if (isNaN(date.getTime())) {
        return '';
      }
    } catch (error) {
      console.error('formatTime: 解析时间出错', error, timestamp);
      return '';
    }
    
    if (fullFormat) {
      try {
        // 完整格式用于时间分隔符显示
        const now = new Date();
        const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
        const msgDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
        const diff = today.getTime() - msgDate.getTime();
        const days = Math.floor(diff / (1000 * 60 * 60 * 24));
        
        const month = date.getMonth() + 1;
        const day = date.getDate();
        const hours = date.getHours();
        const minutes = date.getMinutes();
        const timeStr = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
        
        if (days === 0) {
          // 今天
          return `今天 ${timeStr}`;
        } else if (days === 1) {
          // 昨天
          return `昨天 ${timeStr}`;
        } else if (days < 7) {
          // 本周
          const weekDays = ['日', '一', '二', '三', '四', '五', '六'];
          return `周${weekDays[date.getDay()]} ${timeStr}`;
        } else if (date.getFullYear() === now.getFullYear()) {
          // 今年
          return `${month}月${day}日 ${timeStr}`;
        } else {
          // 跨年
          return `${date.getFullYear()}年${month}月${day}日 ${timeStr}`;
        }
      } catch (error) {
        console.error('formatTime: 格式化时间出错', error, date);
        // 如果格式化失败，至少返回一个简单的时间格式
        const month = date.getMonth() + 1;
        const day = date.getDate();
        const hours = date.getHours();
        const minutes = date.getMinutes();
        return `${month}月${day}日 ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
      }
    }
    
    // 非完整格式（用于消息气泡右下角时间，暂不使用）
    const now = new Date();
    const diff = now.getTime() - date.getTime();
    const minutes = Math.floor(diff / 60000);
    
    if (minutes < 1) return '刚刚';
    if (minutes < 60) return `${minutes}分钟前`;
    if (minutes < 1440) return `${Math.floor(minutes / 60)}小时前`;
    
    const month = date.getMonth() + 1;
    const day = date.getDate();
    const hours = date.getHours();
    const minutesValue = date.getMinutes();
    return `${month}月${day}日 ${hours.toString().padStart(2, '0')}:${minutesValue.toString().padStart(2, '0')}`;
  },
});

